//-----------------------------------------------------------------------
// <copyright file="TFS2008Build.cs" company="FreeToDev">(c) FreeToDev. This source is subject to the Microsoft Permissive License. See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx. All other rights reserved.</copyright>
//-----------------------------------------------------------------------
namespace FreeToDev.MSBuildTasks.TFS2008
{
    using System;
    using System.Globalization;
    using FreeToDev.MSBuildTasks;
    using Microsoft.Build.Framework;
    using Microsoft.TeamFoundation.Build.Client;
    using Microsoft.TeamFoundation.Client;

    /// <summary>
    /// <b>Valid TaskActions are:</b>
    /// <para><i>ShowBuildStep</i> (<b>Required: </b> TeamFoundationServerUrl, BuildUri <b>Optional: </b>BuildStep)</para>
    /// <para><b>Remote Support:</b> NA</para>
    /// </summary>
    /// <example>
    /// <code><![CDATA[
    ///  <!-- This task should only be used within a TFS Team Build proj file -->
    ///  <FTDTFS2008Build TaskAction="ShowBuildStep" TeamFoundationServerUrl="$(TeamFoundationServerUrl)" BuildURI="$(BuildUri)" BuildStep="Your Message Here" />
    /// ]]></code>    
    /// </example>  
    public class FTDTFS2008Build : FTDTaskBase
    {
        private TeamFoundationServer tfs;
        private IBuildStep buildStepI;
        private IBuildDetail build;
        private IBuildServer buildServer;

        /// <summary>
        /// Sets the Url of the Team Foundation Server.
        /// </summary>
        [Required]
        public string TeamFoundationServerUrl { get; set; }

        /// <summary>
        /// Sets the Uri of the Build for which this task is executing.
        /// </summary>
        public string BuildUri { get; set; }

        /// <summary>
        /// Sets the BuildStep message to show
        /// </summary>
        public string BuildStep { get; set; }

        /// <summary>
        /// Lazy init property that gives access to the BuildServer service of the TF Server.
        /// </summary>
        protected IBuildServer BuildServer
        {
            get
            {
                if (this.buildServer == null)
                {
                    this.buildServer = (IBuildServer)this.Tfs.GetService(typeof(IBuildServer));
                }

                return this.buildServer;
            }
        }

        /// <summary>
        /// Lazy init property that gives access to the Build specified by BuildUri.
        /// </summary>
        protected IBuildDetail Build
        {
            get
            {
                if (this.build == null)
                {
                    this.build = this.BuildServer.GetBuild(new Uri(this.BuildUri), null, QueryOptions.None);
                }

                return this.build;
            }
        }

        /// <summary>
        /// Lazy init property that gives access to the TF Server specified by TeamFoundationServerUrl.
        /// </summary>
        protected TeamFoundationServer Tfs
        {
            get
            {
                if (this.tfs == null)
                {
                    this.tfs = TeamFoundationServerFactory.GetServer(this.TeamFoundationServerUrl);
                }

                return this.tfs;
            }
        }

        /// <summary>
        /// When overridden in a derived class, executes the task.
        /// </summary>
        protected override void InternalExecute()
        {
            switch (this.TaskAction)
            {
                case "ShowBuildStep":
                    this.ShowBuildStep();
                    break;
                default:
                    this.Log.LogError(string.Format(CultureInfo.InvariantCulture, "Invalid TaskAction passed: {0}", this.TaskAction));
                    return;
            }
        }

        private void ShowBuildStep()
        {
            bool returnValue = false;
            try
            {
                this.AddBuildStep();
                returnValue = true;
            }
            finally
            {
                this.UpdateBuildStep(returnValue);
            }
        }

        private void AddBuildStep()
        {
            this.buildStepI = InformationNodeConverters.AddBuildStep(this.Build, this.BuildStep, this.BuildStep);
        }

        private void UpdateBuildStep(bool result)
        {
            this.buildStepI.Status = result ? BuildStepStatus.Succeeded : BuildStepStatus.Failed;
            this.buildStepI.FinishTime = DateTime.Now;
            this.buildStepI.Save();
        }
    }
}